#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>

//初始化条件变量
pthread_cond_t   hasTaxi = PTHREAD_COND_INITIALIZER;
//初始化互斥量
pthread_mutex_t  lock = PTHREAD_MUTEX_INITIALIZER;

struct taxi{
	struct taxi *next;
	int num;
};

//生产与消费的资源
struct taxi *Head;

//生产者线程
void * taxiArv(void * arg){
	printf("taxi Arrive Thread\n");
	pthread_detach(pthread_self());
	struct taxi *tx;
	int i = 1;
	while(1){
		tx = malloc(sizeof(struct taxi));
		tx->num = i++;
		printf("taxi %d comming\n", tx->num);
		
		pthread_mutex_lock(&lock);
		//生产资源
		tx->next = Head;
		Head = tx;
		//唤醒单个休眠线程
		pthread_cond_signal(&hasTaxi);
		//唤醒所有休眠线程
		//pthread_cond_broadcast(&hasTaxi);
		pthread_mutex_unlock(&lock);
		sleep(1);
	}
}

//消费者线程
void * takeTaxi(void * arg){
	printf("take taxi Thread\n");
	pthread_detach(pthread_self());
	struct taxi *tx;
	while(1){
		pthread_mutex_lock(&lock);
		//若注释掉这一行，则会出现信号丢失问题或者惊群效应
		while(Head == NULL){
			pthread_cond_wait(&hasTaxi, &lock);
		}
		//消费资源
		tx = Head;
		Head = tx->next;
		printf("Thread %d Take taxi %d\n", (int)arg, tx->num);
		free(tx);
		pthread_mutex_unlock(&lock);
	}
}

int main(){
	pthread_t tid, tid1, tid2, tid3;

	//生产者线程
	pthread_create(&tid, NULL, taxiArv, NULL);

	//消费者线程
	pthread_create(&tid1, NULL, takeTaxi, (void *)1);
	pthread_create(&tid2, NULL, takeTaxi, (void *)2);
	pthread_create(&tid3, NULL, takeTaxi, (void *)3);

	//主线程不退出
	while(1){
		sleep(1);
	}
}
